﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JV.Com.Business
{
    internal class Downloader
    {
        private HttpClient m_client;
        private HttpClient m_validClient;

        private static object m_lockInstance = new object();
        private static Downloader s_instance;
        public static Downloader Instance
        {
            get
            {
                if (s_instance == null)
                {
                    lock (m_lockInstance)
                    {
                        if (s_instance == null)
                        {
                            s_instance = new Downloader();
                        }
                    }
                }

                return s_instance;
            }
        }

        public Downloader()
        {
            m_client = new HttpClient(new RetryHandler(new HttpClientHandler() { Credentials = new NetworkCredential("appandr", "e32!cdf") }));
            m_validClient = new HttpClient(new HttpClientHandler() { Credentials = new NetworkCredential("appandr", "e32!cdf") });
            //m_client.Timeout = TimeSpan.FromSeconds(5);
        }

        public async Task<bool> IsUrlValid(string uri)
        {
            try
            {
                using (var response = await m_validClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead))
                {
                    if(response.IsSuccessStatusCode)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            catch (HttpRequestException ex)
            {
                throw;
            }
            catch
            {
                throw;
            }
        }

        public async Task<string> DownloadStringAsync(string uri)
        {
            try
            {
                using (var response = await m_client.GetAsync(uri))
                {
                    response.EnsureSuccessStatusCode();
                    return await response.Content.ReadAsStringAsync();
                }
            }
            catch (HttpRequestException ex)
            {
                throw;
            }
            catch
            {
                throw;
            }
        }

        public async Task<byte[]> DownloadBytesAsync(string uri)
        {
            using (var response = await m_client.GetAsync(uri))
            {
                try
                {
                    response.EnsureSuccessStatusCode();
                    return await response.Content.ReadAsByteArrayAsync();
                }
                catch
                {
                    throw;
                }
            }
        }

        public class RetryHandler : DelegatingHandler
        {
            private const int MaxRetries = 3;

            public RetryHandler(HttpMessageHandler innerHandler)
                : base(innerHandler)
            { }

            protected override async Task<HttpResponseMessage> SendAsync(
                HttpRequestMessage request,
                CancellationToken cancellationToken)
            {
                HttpResponseMessage response;
                for (int i = 0; i < MaxRetries; i++)
                {
                    try
                    {
                        response = await base.SendAsync(request, cancellationToken);
                        response.EnsureSuccessStatusCode();
                        return response;
                    }
                    catch
                    {
                        
                        response = null;
                        // log
                    }
                }

                throw new HttpRequestException("Erreur lors de la requête HTTP");
            }
        }
    }
}
